package com.qiangesoft.blog.core.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.blog.common.constants.FieldConstants;
import com.qiangesoft.blog.common.mvc.PageQuery;
import com.qiangesoft.blog.common.mvc.PageResultVO;
import com.qiangesoft.blog.common.result.ResponseResult;
import com.qiangesoft.blog.core.entity.BlogCategory;
import com.qiangesoft.blog.core.mapper.BlogCategoryMapper;
import com.qiangesoft.blog.core.pojo.vo.BlogCategorySimpleVO;
import com.qiangesoft.blog.core.pojo.vo.BlogCategoryTreeVO;
import com.qiangesoft.blog.core.service.IBlogArticleService;
import com.qiangesoft.blog.core.service.IBlogCategoryService;
import com.qiangesoft.blog.system.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.qiangesoft.blog.common.constants.FieldConstants.LIMIT_ONE;
import static com.qiangesoft.blog.common.result.ResultCode.CATEGORY_IS_EXIST;
import static com.qiangesoft.blog.common.result.ResultCode.CATEGORY_IS_TOP;

/**
 * <p>
 * 博客分类 服务实现类
 * </p>
 *
 * @author qiange
 * @since 2023-06-05
 */
@Service
public class BlogCategoryServiceImpl extends ServiceImpl<BlogCategoryMapper, BlogCategory> implements IBlogCategoryService {

    @Autowired
    private IBlogArticleService blogArticleService;

    /**
     * 分类列表
     *
     * @param name 分类名
     * @return
     */
    @Override
    public PageResultVO<BlogCategory> listCategory(PageQuery pageQuery, String name) {
        PageResultVO<BlogCategory> pageResultVO = new PageResultVO<>();
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        pageResultVO.setPageNum(pageNum);
        pageResultVO.setPageSize(pageSize);

        Page<BlogCategory> page = baseMapper.selectCategory(new Page<>(pageNum, pageSize), name);
        pageResultVO.setTotal(page.getTotal());
        pageResultVO.setPages(page.getPages());
        pageResultVO.setResults(page.getRecords());
        return pageResultVO;
    }

    /**
     * 分类详情
     *
     * @param id 分类id
     * @return
     */
    @Override
    public ResponseResult getCategoryById(Long id) {
        BlogCategory category = baseMapper.selectById(id);
        return ResponseResult.success(category);
    }

    /**
     * 添加分类
     *
     * @param category 分类对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult insertCategory(BlogCategory category) {
        BlogCategory vo = baseMapper.selectOne(new QueryWrapper<BlogCategory>().eq(FieldConstants.NAME, category.getName()));
        if (ObjectUtil.isNotNull(vo)) {
            throw new BusinessException("该分类名称已存在!");
        }
        int rows = baseMapper.insert(category);
        return rows > 0 ? ResponseResult.success() : ResponseResult.error("添加分类失败");
    }

    /**
     * 修改分类
     *
     * @param category 分类对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateCategory(BlogCategory category) {
        BlogCategory vo = baseMapper.selectOne(new QueryWrapper<BlogCategory>().eq(FieldConstants.NAME, category.getName()));
        Assert.isTrue(!(vo != null && !vo.getId().equals(category.getId())), CATEGORY_IS_EXIST.getDesc());

        int rows = baseMapper.updateById(category);

        return rows > 0 ? ResponseResult.success() : ResponseResult.error("修改分类失败");
    }

    /**
     * 删除分类
     *
     * @param id 分类id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteCategory(Long id) {
        int rows = baseMapper.deleteById(id);
        return rows > 0 ? ResponseResult.success() : ResponseResult.error("删除分类失败");
    }

    /**
     * 批量删除分类
     *
     * @param list
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteBatch(List<BlogCategory> list) {
        List<Long> ids = list.stream().map(BlogCategory::getId).collect(Collectors.toList());
        int rows = baseMapper.deleteBatchIds(ids);
        return rows > 0 ? ResponseResult.success() : ResponseResult.error("批量删除分类失败");
    }

    /**
     * 置顶分类
     *
     * @return 置顶分类
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult top(Long id) {
        BlogCategory category = baseMapper.selectOne(new QueryWrapper<BlogCategory>().orderByDesc(FieldConstants.SORT).last(LIMIT_ONE));
        Assert.isTrue(!category.getId().equals(id), CATEGORY_IS_TOP.getDesc());

        BlogCategory vo = BlogCategory.builder()
                .sort(category.getSort() + 1).updateTime(LocalDateTime.now()).id(id).build();
        int rows = baseMapper.updateById(vo);

        return rows > 0 ? ResponseResult.success() : ResponseResult.error("置顶失败");
    }

    //-----------------web端方法开始-------------

    @Override
    public List<BlogCategorySimpleVO> listAll() {
        return baseMapper.selectAll();
    }

    @Override
    public List<BlogCategoryTreeVO> listTree() {
        List<BlogCategorySimpleVO> voList = baseMapper.selectAll();
        List<BlogCategoryTreeVO> list = new ArrayList<>();
        for (BlogCategorySimpleVO simpleVO : voList) {
            BlogCategoryTreeVO treeVO = new BlogCategoryTreeVO();
            treeVO.setId(simpleVO.getId());
            treeVO.setLabel(simpleVO.getName() + "(" + simpleVO.getArticleNum() + ")");
            treeVO.setChildren(new ArrayList<>());
            list.add(treeVO);
        }
        return list;
    }
}
